﻿using Newtonsoft.Json.Linq;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace Coldairarrow.Util
{
    public class HttpClient
    {
        /// <summary>
        /// Seivice URL
        /// </summary>
        public string Url { get; set; }
        /// <summary>
        /// 内容
        /// </summary>
        public string Content { get; set; }
        /// <summary>
        /// 请求数据类型
        /// </summary>
        public string ContentType { get; set; }
        /// <summary>
        /// 请求的方法
        /// </summary>
        public string Method { get; set; }
        /// <summary>
        /// 自定义头信息
        /// </summary>
        public string Headers { get; set; }
        /// <summary>
        /// Cookie，保证登录后，所有访问持有一个Cookie；
        /// </summary>
        static CookieContainer Cookie = new CookieContainer();

        /// <summary>
        /// HTTP访问POST
        /// </summary>
        public async Task<string> AsyncRequest()
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; //必须加上这一句，根据需要更改值
            HttpWebRequest httpRequest = HttpWebRequest.Create(Url) as HttpWebRequest;
            httpRequest.Method = ContentType.IsNullOrEmpty() ? "POST" : ContentType;
            httpRequest.ContentType = ContentType.IsNullOrEmpty() ? "application/json" : ContentType;
            httpRequest.CookieContainer = Cookie;
            httpRequest.Timeout = 1000 * 60 * 10;//10min


            using (Stream reqStream = await httpRequest.GetRequestStreamAsync())
            {
                var bytes = UnicodeEncoding.UTF8.GetBytes(Content);
                reqStream.Write(bytes, 0, bytes.Length);
                reqStream.Flush();
            }
            //获取服务器响应
            using (var webResponse = await httpRequest.GetResponseAsync())
            //将响应进行流处理
            using (var repStream = webResponse.GetResponseStream())
            {
                using (var reader = new StreamReader(repStream))
                {
                    return ValidateResult(reader.ReadToEnd());
                }
            }
        }

        /// <summary>
        /// HTTP访问POST
        /// </summary>
        public string Request()
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; //必须加上这一句，根据需要更改值
            try
            {

                HttpWebRequest httpRequest = HttpWebRequest.Create(Url) as HttpWebRequest;
                httpRequest.Method = Method.IsNullOrEmpty() ? "POST" : Method;
                httpRequest.ContentType = ContentType.IsNullOrEmpty() ? "application/json" : ContentType;
                httpRequest.CookieContainer = Cookie;
                httpRequest.Timeout = 1000 * 60 * 10;//10min

                if (httpRequest.Method == "POST" && !Content.IsNullOrEmpty())
                {
                    using (Stream reqStream = httpRequest.GetRequestStream())
                    {
                        var bytes = UnicodeEncoding.UTF8.GetBytes(Content);
                        reqStream.Write(bytes, 0, bytes.Length);
                        reqStream.Flush();
                    }
                }
                //获取服务器响应

                using (var webResponse = httpRequest.GetResponse())
                //将响应进行流处理
                using (var repStream = webResponse.GetResponseStream())
                {
                    using (var reader = new StreamReader(repStream))
                    {
                        return ValidateResult(reader.ReadToEnd());
                    }
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }



        /// <summary>
        /// HTTP访问POST
        /// </summary>
        /// <param name="header">请求头数据</param>
        /// <returns></returns>
        public string Request(Header header)
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; //必须加上这一句，根据需要更改值
            try
            {

                HttpWebRequest httpRequest = HttpWebRequest.Create(Url) as HttpWebRequest;
                httpRequest.Method = ContentType.IsNullOrEmpty() ? "POST" : ContentType;
                httpRequest.ContentType = header.IsNullOrEmpty() || header.ContentType.IsNullOrEmpty() ? "application/json" : ContentType;
                httpRequest.CookieContainer = Cookie;
                httpRequest.Timeout = 1000 * 60 * 10;//10min
                if (!header.IsNullOrEmpty() && header.Headers.Count > 0)
                {
                    header.Headers.ForEach(x => httpRequest.Headers.Add(x.Key, x.Value));
                }
                if (httpRequest.Method == "POST")
                {

                    using (Stream reqStream = httpRequest.GetRequestStream())
                    {
                        var bytes = UnicodeEncoding.UTF8.GetBytes(Content);
                        reqStream.Write(bytes, 0, bytes.Length);
                        reqStream.Flush();
                    }
                }
                //获取服务器响应

                using (var webResponse = httpRequest.GetResponse())
                //将响应进行流处理
                using (var repStream = webResponse.GetResponseStream())
                {
                    using (var reader = new StreamReader(repStream))
                    {
                        return ValidateResult(reader.ReadToEnd());
                    }
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }


        /// <summary>
        /// HTTP访问POST
        /// </summary>
        /// <param name="header">请求头数据</param>
        /// <returns></returns>
        public async Task<string> RequestAsync(Header header)
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; //必须加上这一句，根据需要更改值
            try
            {

                HttpWebRequest httpRequest = HttpWebRequest.Create(Url) as HttpWebRequest;
                httpRequest.Method = ContentType.IsNullOrEmpty() ? "POST" : ContentType;
                httpRequest.ContentType = header.IsNullOrEmpty() || header.ContentType.IsNullOrEmpty() ? "application/json" : header.ContentType;
                httpRequest.CookieContainer = Cookie;
                httpRequest.Timeout = 1000 * 60 * 10;//10min
                if (header.Headers.Count > 0)
                {
                    header.Headers.ForEach(x => httpRequest.Headers.Add(x.Key, x.Value));
                }
                if (httpRequest.Method == "POST")
                {

                    using (Stream reqStream = await httpRequest.GetRequestStreamAsync())
                    {
                        var bytes = UnicodeEncoding.UTF8.GetBytes(Content);
                        reqStream.Write(bytes, 0, bytes.Length);
                        reqStream.Flush();
                    }
                }
                //获取服务器响应

                using (var webResponse = await httpRequest.GetResponseAsync())
                //将响应进行流处理
                using (var repStream = webResponse.GetResponseStream())
                {
                    using (var reader = new StreamReader(repStream))
                    {
                        return ValidateResult(await reader.ReadToEndAsync());
                    }
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }


        /// <summary>
        /// HTTP文件请求转换成Execl
        /// </summary>
        public string FileRequest(string path)
        {
            // ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验
            //System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3 | (SecurityProtocolType)3072; //必须加上这一句，根据需要更改值
            try
            {
                if (!Url.IsNullOrEmpty() && !path.IsNullOrEmpty())
                {
                    HttpWebRequest httpRequest = HttpWebRequest.Create(Url) as HttpWebRequest;
                    //httpRequest.Method = Method.IsNullOrEmpty() ? "POST" : Method;
                    //httpRequest.ContentType = ContentType.IsNullOrEmpty() ? "application/json" : ContentType;
                    //httpRequest.CookieContainer = Cookie;
                    //httpRequest.Timeout = 1000 * 60 * 10;//10min

                    //if (httpRequest.Method == "POST" && !Content.IsNullOrEmpty())
                    //{
                    //    using (Stream reqStream = httpRequest.GetRequestStream())
                    //    {
                    //        var bytes = UnicodeEncoding.UTF8.GetBytes(Content);
                    //        reqStream.Write(bytes, 0, bytes.Length);
                    //        reqStream.Flush();
                    //    }
                    //}
                    //获取服务器响应

                    using (var webResponse = httpRequest.GetResponse())
                    //将响应进行流处理
                    using (var repStream = webResponse.GetResponseStream())
                    {
                        //文件流，流信息读到文件流中，读完关闭
                        using (FileStream fs = File.Create(path))
                        {
                            //建立字节组，并设置它的大小是多少字节
                            byte[] bytes = new byte[1024000];
                            int n = 1;
                            while (n > 0)
                            {
                                //一次从流中读多少字节，并把值赋给Ｎ，当读完后，Ｎ为０,并退出循环
                                n = repStream.Read(bytes, 0, 1024000);
                                fs.Write(bytes, 0, n); //将指定字节的流信息写入文件流中
                            }

                        }
                    }

                }
                return "OK";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }


        /// <summary>
        /// HTTP请求获取EXECL并通过委托将结果传出
        /// </summary>
        /// <param name="action">通过委托操作工作表</param>
        /// <returns>返回状态</returns>
        public string FileRequestExecl(Action<ExcelWorksheets> action)
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; //必须加上这一句，根据需要更改值
            try
            {

                if (!Url.IsNullOrEmpty())
                {
                    HttpWebRequest httpRequest = HttpWebRequest.Create(Url) as HttpWebRequest;
                    //获取服务器响应
                    using (var webResponse = httpRequest.GetResponse())
                    //将响应进行流处理
                    using (var repStream = webResponse.GetResponseStream())
                    using (var memoryStream = new MemoryStream())
                    {
                        repStream.CopyTo(memoryStream);
                        memoryStream.Position = 0; // 重置流的位置

                        // 创建 ExcelPackage 对象
                        using (ExcelPackage package = new ExcelPackage(memoryStream))
                        {
                            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
                            var worksheet = package.Workbook.Worksheets;
                            action.Invoke(worksheet);
                        }
                    }

                }
                return "OK";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// HTTP请求获取EXECL并通过委托将结果传出
        /// </summary>
        /// <param name="action">通过委托操作工作表</param>
        /// <returns>返回状态</returns>
        public async Task<string> FileRequestExeclAsync(Func<ExcelWorksheets, Task> callback)
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; //必须加上这一句，根据需要更改值
            try
            {

                if (!Url.IsNullOrEmpty())
                {
                    HttpWebRequest httpRequest = HttpWebRequest.Create(Url) as HttpWebRequest;
                    //获取服务器响应
                    using (var webResponse = await httpRequest.GetResponseAsync())
                    //将响应进行流处理
                    using (var repStream = webResponse.GetResponseStream())
                    using (var memoryStream = new MemoryStream())
                    {
                        repStream.CopyTo(memoryStream);
                        memoryStream.Position = 0; // 重置流的位置

                        // 创建 ExcelPackage 对象
                        using (ExcelPackage package = new ExcelPackage(memoryStream))
                        {
                            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
                            var worksheet = package.Workbook.Worksheets;
                            await callback.Invoke(worksheet);
                        }
                    }

                }
                return "OK";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }


        /// <summary>
        /// HTTP文件请求并保存到指定路径
        /// </summary>
        public string FileRequestText()
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; //必须加上这一句，根据需要更改值
            string text = null;
            try
            {

                if (!Url.IsNullOrEmpty())
                {
                    HttpWebRequest httpRequest = HttpWebRequest.Create(Url) as HttpWebRequest;
                    //获取服务器响应
                    using (var webResponse = httpRequest.GetResponse())
                    //将响应进行流处理
                    using (var repStream = webResponse.GetResponseStream())
                    using (var stream = new StreamReader(repStream))
                    {
                        text = stream.ReadToEnd();

                    }

                }
                return text;
            }
            catch (Exception ex)
            {
                return text;
            }
        }
        /// <summary>
        /// HTTP请求获取文件的base64吗
        /// </summary>
        /// <param name="action">通过委托操作工作表</param>
        /// <returns>返回状态</returns>
        public async Task<string> FileRequestBase64Async()
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault; //必须加上这一句，根据需要更改值
            try
            {

                if (!Url.IsNullOrEmpty())
                {
                    using var client = new System.Net.Http.HttpClient();
                    byte[] fileBytes = await client.GetByteArrayAsync(Url);
                    return Convert.ToBase64String(fileBytes);
                }
                return "OK";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private static string ValidateResult(string responseText)
        {
            if (responseText.StartsWith("response_error:"))
            {
                return responseText.TrimStart("response_error:".ToCharArray());
            }
            return responseText;
        }

        public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            //直接确认，否则打不开    
            return true;

        }
    }


    public class Header
    {
        public string ContentType { get; set; }
        public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();


    }
}
